package com.ev;

import com.ev.entity.SummaryTable;
import com.ev.util.XlsExcelUtil;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.Transaction;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author: GuoShouFu
 * @Date: 2022/6/27
 **/
public class GenericShp2 {

    /**
     * 生成要素类型
     *
     * @param geometryClazz 类型
     * @return 要素类型
     */
    private static SimpleFeatureType createFeatureType(Class<? extends Geometry> geometryClazz) {
        SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
        builder.setName("Location");
        // <- Coordinate reference system
        builder.setCRS(DefaultGeographicCRS.WGS84);

        // add attributes in order
        builder.add("the_geom", geometryClazz);
        // <- 15 chars width for name field

//        String[] array = new String[]{"YEAR", "外业核查内容", "地块编号", "经度", "纬度", "DLMC", "DLDM", "是否变化", "GD", "YBD"
//                , "EMC", "EDM", "照片文件路径", "林分结构", "优势树草种", "乔木郁闭度", "灌草盖度", "林下综合盖度", "综合盖度"
//                , "坡度", "坡向", "株距", "行距", "冠幅", "生长周期", "梯田设计标准", "梯田类型", "田面宽度", "边坎类型", "梯田质量"
//                , "损毁程度", "开垦利用方式", "所处地貌类型区", "所在区域", "对应的项目部位", "水土流失治理度", "项目所处的建设阶段"
//                , "扰动方式", "QDLX", "QDDM", "BZ", "核查矢量编号", "检查", "TDLYDM_SL", "EDM_SL", "QD202153"};

        String[] array = new String[]{"YEAR", "WYHCNR", "DKBH", "经度", "纬度", "DLMC", "DLDM", "BH", "YBD", "GD"
                , "EMC", "EDM", "照片", "LFJG", "YSSCZ", "QMYBD", "GCGD", "LXZHGD", "ZHGD"
                , "坡度", "坡向", "株距", "行距", "冠幅", "SZZQ", "TTSJBZ", "TTLX", "TMKD", "BKLX", "TTZL"
                , "SHCD", "KKLYFS", "SCDMLXQ", "SZQY", "XMBW", "ZLD", "JSJD"
                , "RDFS", "QDLX", "QDDM", "BZ", "SLBH", "检查", "TDLYDM_SL", "EDM_SL", "QD202153"
                , "SFSCJSXM", "SCJSXMLX", "SFSG", "SFSSSBCS", "SBCSLX", "SBCSSL", "BDM", "TMC", "标记", "程序QD"};
        for (String s : array) {
            builder.length(100).add(s, String.class);
        }
        // build the type
        return builder.buildFeatureType();
    }

    /**
     * xml文件的记录封装到SimpleFeature集合中
     *
     * @param type                            要素类型
     * @param xlsFile                         xls文件
     * @param relativePathOfPhotoDirectoryMap 点位id和照片相对路径的map集合
     * @return
     * @throws IOException
     */
    private static List<SimpleFeature> readXls2FeatureList(SimpleFeatureType type, File xlsFile, Map<String, String> relativePathOfPhotoDirectoryMap) throws Exception {
        //A list to collect result as we create them.
        List<SimpleFeature> result = new ArrayList<>();

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);

        XlsExcelReader reader = new XlsExcelReader(xlsFile);

        List<List<String>> read = reader.read(0);
        List<SummaryTable> summaryTableList = XlsExcelUtil.listStringConvert2Entity(read, SummaryTable.class);

        for (SummaryTable summaryTable : summaryTableList) {
            if ("".equals(summaryTable.getId()) || summaryTable.getId() == null) {
                continue;
            }
            Point point = geometryFactory.createPoint(new Coordinate(Double.parseDouble(summaryTable.getLongitude()),
                    Double.parseDouble(summaryTable.getLatitude())));
            featureBuilder.add(point);
            featureBuilder.add(summaryTable.getYear());
            featureBuilder.add(summaryTable.getVerification());
            featureBuilder.add(summaryTable.getLandNo());
            featureBuilder.add(summaryTable.getLongitude());
            featureBuilder.add(summaryTable.getLatitude());
            featureBuilder.add(summaryTable.getDLMC());
            featureBuilder.add(summaryTable.getDLDM());
            featureBuilder.add(summaryTable.getBH());
            featureBuilder.add(summaryTable.getYBD());
            featureBuilder.add(summaryTable.getGD());
            featureBuilder.add(summaryTable.getEMC());
            featureBuilder.add(summaryTable.getEDM());

            featureBuilder.add(relativePathOfPhotoDirectoryMap.get(summaryTable.getId()));
            featureBuilder.add(summaryTable.getStandStructure());
            featureBuilder.add(summaryTable.getDominantTreeAndGrassSpecies());
            featureBuilder.add(summaryTable.getArborCanopyDensity());
            featureBuilder.add(summaryTable.getShrubGrassCoverage());
            featureBuilder.add(summaryTable.getUndergrowthComprehensiveCoverage());
            featureBuilder.add(summaryTable.getComprehensiveVoverage());
            featureBuilder.add(summaryTable.getSlope());
            featureBuilder.add(summaryTable.getAspectOfSlope());
            featureBuilder.add(summaryTable.getPlantSpacing());
            featureBuilder.add(summaryTable.getRowSpacing());
            featureBuilder.add(summaryTable.getCrownWidth());
            featureBuilder.add(summaryTable.getGrowthCycle());
            featureBuilder.add(summaryTable.getTerraceDesignStandard());
            featureBuilder.add(summaryTable.getTerraceType());
            featureBuilder.add(summaryTable.getFieldWidth());
            featureBuilder.add(summaryTable.getEdgeSillType());
            featureBuilder.add(summaryTable.getTerraceQuality());
            featureBuilder.add(summaryTable.getDamageDegree());
            featureBuilder.add(summaryTable.getUtilizationMode());
            featureBuilder.add(summaryTable.getAreaType());
            featureBuilder.add(summaryTable.getArea());
            featureBuilder.add(summaryTable.getProjectLocation());
            featureBuilder.add(summaryTable.getWaterAndSoilLoss());
            featureBuilder.add(summaryTable.getJSJD());
            featureBuilder.add(summaryTable.getDisturbanceMode());
            featureBuilder.add(summaryTable.getQDLX());
            featureBuilder.add(summaryTable.getQDDM());
            featureBuilder.add(summaryTable.getBZ());
            featureBuilder.add(summaryTable.getVerifyVectorNumber());
            featureBuilder.add(summaryTable.getInspect());
            featureBuilder.add(summaryTable.getTDLYDM_SL());
            featureBuilder.add(summaryTable.getEDM_SL());
            featureBuilder.add(summaryTable.getQD202153());
            featureBuilder.add(summaryTable.getSFSCJSXM());
            featureBuilder.add(summaryTable.getSCJSXMLX());
            featureBuilder.add(summaryTable.getSFSG());
            featureBuilder.add(summaryTable.getSFSSSBCS());
            featureBuilder.add(summaryTable.getSBCSLX());
            featureBuilder.add(summaryTable.getSBCSSL());
            featureBuilder.add(summaryTable.getBDM());
            featureBuilder.add(summaryTable.getTMC());
            featureBuilder.add(summaryTable.getMark());
            featureBuilder.add(summaryTable.getQD());
            SimpleFeature feature = featureBuilder.buildFeature(summaryTable.getId());
            result.add(feature);
        }

        return result;
    }


    public static void main(String[] args) throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put("1", "路径一");
        map.put("2", "路径二");
        genericShp("D:\\记录\\华油\\测试数据（表格+照片）\\测试数据（表格+照片）\\汇总表格0629.xls"
                , "C:\\Users\\55072\\Desktop\\新建文件夹 (2)\\汇总表格-测试数据改.shp", map);

    }

    /**
     * 生成shp文件
     *
     * @param summaryTablePath                汇总表路径
     * @param exportPath                      导出路径
     * @param relativePathOfPhotoDirectoryMap id与照片对饮关系的map
     * @throws Exception
     */
    public static void genericShp(String summaryTablePath, String exportPath, Map<String, String> relativePathOfPhotoDirectoryMap) throws Exception {

        //Create a FeatureType
        SimpleFeatureType type = createFeatureType(Point.class);

        //将xml转换为feature
        List<SimpleFeature> features = readXls2FeatureList(type, new File(summaryTablePath), relativePathOfPhotoDirectoryMap);

        ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();

        File exportFile = new File(exportPath);
        genericParentPath(exportFile);

        Map<String, Serializable> params = new HashMap<>(2);
        params.put("url", exportFile.toURI().toURL());
        params.put("create spatial index", Boolean.TRUE);

        ShapefileDataStore newDataStore =
                (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);

        newDataStore.setCharset(Charset.forName("GBK"));
        //TYPE is used as a template to describe the file contents
        newDataStore.createSchema(type);

        //Write the features to the shapefile
        Transaction transaction = new DefaultTransaction("create");

        String typeName = newDataStore.getTypeNames()[0];
        SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);

        if (featureSource instanceof SimpleFeatureStore) {
            SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
            SimpleFeatureCollection collection = new ListFeatureCollection(type, features);
            featureStore.setTransaction(transaction);
            try {
                featureStore.addFeatures(collection);
                transaction.commit();
            } catch (Exception problem) {
                problem.printStackTrace();
                transaction.rollback();
            } finally {
                transaction.close();
            }
            System.exit(0);
        } else {
            System.out.println(typeName + " does not support read/write access");
            System.exit(1);
        }
    }

    /**
     * 生成父路径
     *
     * @param file 目标文件
     */
    private static void genericParentPath(File file) {
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
    }


}
